#include <std.h>
#include <memory.h>
#include <shell.h>
#include <error.h>


#define CMD_SEPARATOR ' '
#define USR_INP 256

struct cmd_list	{
	char *cmd_name;
	char *help;
	int (*function)(struct param_list *params);
	int nr_params; /*This value is used to generate the parameter list*/
	struct cmd_list *next;
}*cmd_list=NULL,*tail=NULL;

void register_cmd(char *name,int (*function)(struct param_list *params),int nr_params,char *help)
{
	if(!cmd_list)	{
		cmd_list=new(struct cmd_list);
		tail=cmd_list;
	} else	{
		tail->next=new(struct cmd_list);
		tail=tail->next;
	}
	tail->next=NULL;
	tail->cmd_name=name;
	tail->help=help;
	tail->function=function;
	tail->nr_params=nr_params;
}

struct cmd_list *find_command(char *name)
{
	struct cmd_list *temp;
	for(temp=cmd_list;temp!=NULL;temp=temp->next)	{
		if(!strcmp(temp->cmd_name,name))
			return temp;
	}
	return NULL;
}

void destroy_list(struct param_list *params)
{
	struct param_list *param,*t;
	for(t=params;t;)	{
		param=t->next;
		free(t);
		t=param;
	}
}

/*Parse the input and call the command with the specified parameters*/
void parse_input(char *input)
{
	char cmd_name[USR_INP];
	struct cmd_list *cmd;
	struct param_list *param=NULL,*params=NULL;
	int i;
	getstringparameter(input,cmd_name,CMD_SEPARATOR,NULL);
	if(!(cmd=find_command(cmd_name)))	{
		printk("\nCommand not registered");
		return;
	}
	/*Now build the parameter list*/
	for(i=NULL;i<cmd->nr_params;i++)	{
		if(!param)	{
			param=new(struct param_list);
			param->next=NULL;
			if(!params)
				params=param;
		}
		getstringparameter(input,param->string,' ',1);
		param->integer=getnumber(param->string);
		param=param->next;
	}
	/*Dispatch the command*/
	cmd->function(params);
	destroy_list(params);
}

int help(struct param_list *params)
{
	struct cmd_list *temp;
	printk("\nRegistered commands:");
	for(temp=cmd_list;temp!=NULL;temp=temp->next)	{
		printk("\n%s <%d> %s",temp->cmd_name,temp->nr_params,temp->help);
	}
}

char *shell_string="";

void set_shell_string(char *string)
{
	shell_string=string;
}

void shell_start()
{
	char *inp;
	inp=(char *)malloc(USR_INP * sizeof(char));
	register_cmd("help",help,1,"Help on all the registered commands");
	while(1)	{
		printk("\n%s>",shell_string);
		gets(inp,USR_INP);
		parse_input(inp);
	}
}
